package com.example.dragview.demo

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Canvas
import android.util.AttributeSet
import android.util.Log
import android.view.MotionEvent
import android.view.View
import android.widget.LinearLayout
import androidx.core.math.MathUtils
import androidx.core.view.ViewCompat
import androidx.customview.widget.ViewDragHelper

class DragLayout : LinearLayout {

  private var dragHelper: ViewDragHelper? = null
  private val callback = object : ViewDragHelper.Callback() {
    override fun tryCaptureView(child: View, pointerId: Int): Boolean {
      return true
    }

    override fun clampViewPositionHorizontal(child: View, left: Int, dx: Int): Int {
      val leftBound = paddingLeft
      val rightBound = width - child.width - paddingRight
      return MathUtils.clamp(left, leftBound, rightBound)
    }

    override fun clampViewPositionVertical(child: View, top: Int, dy: Int): Int {
      return top
    }

    override fun onViewReleased(releasedChild: View, xvel: Float, yvel: Float) {
      super.onViewReleased(releasedChild, xvel, yvel)
      dragHelper?.settleCapturedViewAt(50, 50)
      ViewCompat.postInvalidateOnAnimation(this@DragLayout)
    }
  }

  constructor(context: Context) : this(context, null)
  constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
  constructor(
    context: Context,
    attrs: AttributeSet?,
    defStyleAttr: Int
  ) : super(context, attrs, defStyleAttr)

  init {
    dragHelper = ViewDragHelper.create(this, callback)
  }

  override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
    return dragHelper?.shouldInterceptTouchEvent(ev)?: super.onInterceptTouchEvent(ev)
  }

  @SuppressLint("ClickableViewAccessibility")
  override fun onTouchEvent(event: MotionEvent?): Boolean {
    event?.let {
      dragHelper?.processTouchEvent(event)
    }
    // 注意此处需要return true才行
    return true
  }

  override fun computeScroll() {
    super.computeScroll()
    if (dragHelper?.continueSettling(true) == true) {
      ViewCompat.postInvalidateOnAnimation(this);
    }
  }

  override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec)
    Log.d(TAG, "onMeasure")
  }

  override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
    super.onLayout(changed, left, top, right, bottom)
    Log.d(TAG, "onLayout $left-$right/$top-$bottom")
  }

  override fun onDraw(canvas: Canvas?) {
    super.onDraw(canvas)
    Log.d(TAG, "onDraw")
  }

  companion object {
    private const val TAG = "DragLayout"
  }
}